package com.brucekong.slm.common;

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.brucekong.slm.config.CustomConfig.UPLOAD_URL;


/**
 * 文件上传类
 */
public class UploadUtil {

    /**
     * 单文件上传
     */
    public static Map<String, Object> singleupload(MultipartFile file, HttpServletRequest request)
            throws IllegalStateException, IOException {

        if (file.isEmpty()) {
            return null;
        }

        HashMap<String, Object> map = new HashMap<>();

        String realNameWithType = file.getOriginalFilename();

        long size = file.getSize();
        //获取文件后缀名
        String type = getType(realNameWithType);
        String realName = getName(realNameWithType);
        //随机重命名
        String saveName = generateFileName(realName);

        Date d = new Date();
        // 格式化需要存储的时间
        String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(d);
        // 日期路径
        String ymd = new SimpleDateFormat("yyyy/MM/dd").format(d);
        String url = UPLOAD_URL + ymd;

        // 重新获取服务器的路径
        //String dirPath = request.getSession().getServletContext().getRealPath(url);
        // System.out.println("dirPath："+dirPath);
        // 当上传文件是带后缀格式的文件时，设置后缀样式
        File targetFile = new File(url, saveName + realNameWithType);

        // 获取父目录
        File pfile = new File(url);
        // 判断如果目录不存在，先创建
        if (!pfile.exists()) pfile.mkdirs();

        // 文件传输
        file.transferTo(targetFile);

        // 当上传的是无格式文件，则定义为file类型
        if (type.equals("")) {
            type = "file";
            realName = realNameWithType;
        }

        map.put("realName", realName);// 文件原名称
        map.put("size", size);
        map.put("type", type);
        map.put("saveName", saveName);// 文件新名称
        map.put("url", url + "/");
        map.put("time", time);

        return map;
    }

    /**
     * 多文件上传
     */
    public static List<Map<String, Object>> mutilUpload(MultipartFile[] files, HttpServletRequest request)
            throws IllegalStateException, IOException {

        if (files.length > 0) return null;

        //创建这个集合保存所有文件的信息
        List<Map<String, Object>> listMap = new ArrayList<>();

        //循环多次上传多个文件
        for (MultipartFile file : files) {

            //创建map对象保存每一个文件的信息
            Map<String, Object> map = singleupload(file, request);

            listMap.add(map);
        }
        return listMap;
    }

    /**
     * 文件重命名
     */
    private static String generateFileName(String fileName) {
        return UUID.randomUUID().toString();
    }

    /**
     * 得到文件的类型。
     */
    private static String getType(String fileName) {
        int point = fileName.lastIndexOf('.');
        int length = fileName.length();
        if (point == -1 || point == length - 1) {
            return "";
        } else {
            return fileName.substring(point + 1, length);
        }
    }

    /**
     * 得到文件的名称。
     */
    private static String getName(String fileName) {
        int point = fileName.lastIndexOf('.');
        int length = fileName.length();
        if (point == -1 || point == length - 1) {
            return "";
        } else {
            return fileName.substring(0, point);
        }
    }

    /**
     * 将文件的字节数转换成文件的大小
     */
    private static String formatSize(long size) {
        float fsize = size;
        String fileSizeString;
        if (fsize < 1024) {
            fileSizeString = String.format("%.2f", fsize) + "B"; //2f表示保留两位小数
        } else if (fsize < 1048576) {
            fileSizeString = String.format("%.2f", fsize / 1024) + "KB";
        } else if (fsize < 1073741824) {
            fileSizeString = String.format("%.2f", fsize / 1024 / 1024) + "MB";
        } else if (fsize < 1024 * 1024 * 1024) {
            fileSizeString = String.format("%.2f", fsize / 1024 / 1024 / 1024) + "GB";
        } else {
            fileSizeString = "0B";
        }
        return fileSizeString;
    }
}
